package com.zcyh.exam.service.education;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zcyh.exam.constants.EnumConstants;
import com.zcyh.exam.constants.defal.EnumHelper;
import com.zcyh.exam.constants.defal.EnumItem;
import com.zcyh.exam.mapper.education.QuestionInfoMapper;
import com.zcyh.exam.model.common.PageInfo;
import com.zcyh.exam.model.common.ResultCode;
import com.zcyh.exam.model.dto.QuestionInfoAnswer;
import com.zcyh.exam.model.dto.QuestionInfoDto;
import com.zcyh.exam.model.entity.QuestionInfo;
import com.zcyh.exam.model.entity.QuestionType;
import com.zcyh.exam.model.entity.StudentQuestionAnswer;
import com.zcyh.exam.model.entity.TestPaperQuestionInfo;
import com.zcyh.exam.model.request.PageParam;
import com.zcyh.exam.model.request.QuestionInfoQuery;
import com.zcyh.exam.model.response.QuestionGroupItemResponse;
import com.zcyh.exam.parser.QuestionImportParserManager;
import com.zcyh.exam.parser.base.QuestionImportParser;
import com.zcyh.exam.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 试题管理
 * @author zengjintao
 * @version 1.0
 * @create_at 2020/11/19 11:02
 */
@Service
public class QuestionInfoService extends BaseService<QuestionInfoMapper, QuestionInfo> {

    @Autowired
    private TestPaperQuestionInfoService testPaperQuestionInfoService;
    @Autowired
    private StudentQuestionAnswerService studentQuestionAnswerService;

    @Autowired
    private QuestionTypeService questionTypeService;

    /**
     * 试题分页列表
     * @param pageParam
     * @param questionInfoQuery
     * @return
     */
    public PageInfo<QuestionInfoDto> selectPageList(PageParam pageParam, QuestionInfoQuery questionInfoQuery) {
        Page<QuestionInfoDto> page = new Page<>(pageParam.getPageNumber(), pageParam.getPageSize());
        return selectPage(baseMapper.selectPageList(page, questionInfoQuery));
    }
    /**
     * 添加或修改试题
     * 同步修改类型下的考题数量
     * @param questionInfo
     * @return
     */
    @Transactional
    public ResultCode saveOrUpdateQuestionInfo(QuestionInfo questionInfo) {
        QuestionType questionType = questionTypeService.getById(questionInfo.getTypeId());
        boolean updateType = true;
        String questionInfoId = questionInfo.getId();
        if (ObjectUtils.isNotEmpty(questionInfoId)) {
            if (!this.verificationQuestionInfo(questionInfoId)) {
                return new ResultCode(ResultCode.FAIL, "试题已被使用，禁止修改");
            }
            QuestionInfo dbQuestionInfo = getById(questionInfoId);
            String typeId = dbQuestionInfo.getTypeId();
            if(!questionInfo.getTypeId().equals(typeId)){
                QuestionType dbQuestionType = questionTypeService.getById(typeId);
                dbQuestionType.setNum(dbQuestionType.getNum()-1);
                questionTypeService.updateById(dbQuestionType);
            }else{
                //修改没有修改类型
                updateType=false;
            }
        }
        if(updateType){
            questionType.setNum(questionType.getNum()+1);
            questionTypeService.updateById(questionType);
        }
        super.saveOrUpdate(questionInfo);
        return new ResultCode(ResultCode.SUCCESS, "操作成功");
    }


    public QuestionInfo selectById(String id) {
        return baseMapper.selectById(id);
    }
    public ResultCode deleteById(String questionInfoId) {
        if (verificationQuestionInfo(questionInfoId)) {
            super.removeById(questionInfoId);
            return new ResultCode(ResultCode.SUCCESS, "删除成功");
        }
        return new ResultCode(ResultCode.FAIL, "试题已被使用，无法删除");

    }
    public int importQuestion( List<QuestionInfo> questionInfoList) {
        questionInfoList.forEach(questionInfo -> {
            String questionTypeName = questionInfo.getQuestionTypeName();
            EnumItem enumItem = EnumHelper.getEnumItem(EnumConstants.QuestionType.class,questionTypeName);
            EnumConstants.QuestionType value =EnumConstants.QuestionType.values()[enumItem.getIndex()];
            questionInfo.setQuestionType(value);
            QuestionImportParser excelQuestionParser = QuestionImportParserManager.build()
                    .createExcelQuestionParser(questionInfo.getQuestionType());
            questionInfo.setAnswer(excelQuestionParser.parseAnswerText(questionInfo.getAnswer()));
            questionInfo.setOptions(excelQuestionParser.parseOptionText(questionInfo.getOptions()));
            questionInfo.setCreateTime(new Date());
        });
        super.saveBatch(questionInfoList);
        return questionInfoList.size();
    }
    /**
     * 检查试题是否被使用
     * @param questionInfoId
     * @return
     */
    private boolean verificationQuestionInfo(String questionInfoId) {
        LambdaQueryWrapper queryWrapper = Wrappers.<TestPaperQuestionInfo>lambdaQuery()
                .eq(TestPaperQuestionInfo::getQuestionInfoId, questionInfoId)
                .last(" limit 1");
        TestPaperQuestionInfo testPaperQuestionInfo = testPaperQuestionInfoService.getOne(queryWrapper);
        if (ObjectUtils.isNotEmpty(testPaperQuestionInfo)) {
            return false;
        }
        StudentQuestionAnswer studentQuestionAnswer = studentQuestionAnswerService.selectByQuestionInfoId(questionInfoId);
        if (ObjectUtils.isNotEmpty(studentQuestionAnswer)) {
            return false;
        }
        return true;
    }
    /**
     * 对用户作答试题分组
     * @param questionInfoAnswerList
     * @return
     */
    public List<QuestionGroupItemResponse> groupQuestion(List<QuestionInfoAnswer> questionInfoAnswerList) {
        List<QuestionGroupItemResponse> list = new ArrayList<>();
        for (EnumConstants.QuestionType item : EnumConstants.QuestionType.values()) {
            int value = item.getValue();
            List<QuestionInfoAnswer> questionList = questionInfoAnswerList.stream()
                    .filter(questionInfoAnswer -> value == questionInfoAnswer.getQuestionType().getValue())
                    .collect(Collectors.toList());
            if (ObjectUtils.isNotEmpty(questionList)) {
                QuestionGroupItemResponse examQuestionItemResponse = new QuestionGroupItemResponse();
                examQuestionItemResponse.setQuestionTypeName(item.getName());
                examQuestionItemResponse.setQuestionInfoAnswerList(questionList);
                list.add(examQuestionItemResponse);
            }
        }
        return list;
    }
}
